package cn.hamster3.mc.plugin.ball.velocity.listener;

import cn.hamster3.mc.plugin.ball.common.api.BallAPI;
import cn.hamster3.mc.plugin.ball.common.entity.BallServerType;
import cn.hamster3.mc.plugin.ball.common.event.operate.*;
import cn.hamster3.mc.plugin.ball.velocity.HamsterBallPlugin;
import cn.hamster3.mc.plugin.core.common.api.CoreAPI;
import com.google.common.eventbus.Subscribe;
import com.velocitypowered.api.proxy.Player;
import com.velocitypowered.api.proxy.ProxyServer;
import com.velocitypowered.api.proxy.ServerConnection;
import com.velocitypowered.api.proxy.server.RegisteredServer;
import com.velocitypowered.api.proxy.server.ServerInfo;
import net.kyori.adventure.audience.Audience;

import java.util.UUID;

public class BallVelocityListener {
    public static final BallVelocityListener INSTANCE = new BallVelocityListener();

    private BallVelocityListener() {
    }

    @Subscribe
    public void onDispatchConsoleCommand(DispatchConsoleCommandEvent event) {
        if (event.getType() != null && event.getType() != BallServerType.PROXY) {
            return;
        }
        if (event.getServerID() != null && !BallAPI.getInstance().isLocalServer(event.getServerID())) {
            return;
        }
        ProxyServer server = HamsterBallPlugin.getInstance().getProxyServer();
        server.getCommandManager().executeAsync(server.getConsoleCommandSource(), event.getCommand());
    }

    @Subscribe
    public void onDispatchPlayerCommand(DispatchPlayerCommandEvent event) {
        if (event.getType() != null && event.getType() != BallServerType.GAME) {
            return;
        }
        ProxyServer server = HamsterBallPlugin.getInstance().getProxyServer();
        if (event.getUuid() != null) {
            Player player = server.getPlayer(event.getUuid()).orElse(null);
            if (player == null) {
                return;
            }
            server.getCommandManager().executeAsync(player, event.getCommand());
            return;
        }
        for (Player player : server.getAllPlayers()) {
            server.getCommandManager().executeAsync(player, event.getCommand());
        }
    }

    @Subscribe
    public void onKickPlayer(KickPlayerEvent event) {
        ProxyServer server = HamsterBallPlugin.getInstance().getProxyServer();
        Player player = server.getPlayer(event.getUuid()).orElse(null);
        if (player == null) {
            return;
        }
        player.disconnect(event.getReason());
    }

    @Subscribe
    public void onSendMessageToPlayer(SendMessageToPlayerEvent event) {
        for (UUID receiver : event.getReceivers()) {
            Audience audience = CoreAPI.getInstance().getAudienceProvider().player(receiver);
            event.getMessage().show(audience);
        }
    }

    @Subscribe
    public void onSendPlayerToLocation(SendPlayerToLocationEvent event) {
        ProxyServer proxyServer = HamsterBallPlugin.getInstance().getProxyServer();
        String serverID = event.getLocation().getServerID();
        RegisteredServer toServer = proxyServer.getServer(serverID).orElse(null);
        if (toServer == null) {
            HamsterBallPlugin.getInstance().getLogger().warning("试图传送玩家时失败: 服务器 " + serverID + " 不在线");
            return;
        }
        for (UUID uuid : event.getSendPlayerUUID()) {
            Player player = proxyServer.getPlayer(uuid).orElse(null);
            if (player == null) {
                continue;
            }
            RegisteredServer currentServer = player.getCurrentServer().map(ServerConnection::getServer).orElse(null);
            if (currentServer != null && currentServer.getServerInfo().getName().equals(serverID)) {
                continue;
            }
            player.createConnectionRequest(toServer).fireAndForget();
        }
    }

    @Subscribe
    public void onSendPlayerToPlayer(SendPlayerToPlayerEvent event) {
        ProxyServer proxyServer = HamsterBallPlugin.getInstance().getProxyServer();
        UUID toPlayerUUID = event.getToPlayerUUID();
        Player toPlayer = proxyServer.getPlayer(toPlayerUUID).orElse(null);
        if (toPlayer == null) {
            HamsterBallPlugin.getInstance().getLogger().warning("试图传送玩家时失败: 目标玩家 " + toPlayerUUID + " 不在线");
            return;
        }
        RegisteredServer toServer = toPlayer.getCurrentServer().map(ServerConnection::getServer).orElse(null);
        if (toServer == null) {
            HamsterBallPlugin.getInstance().getLogger().warning("试图传送玩家时失败: 目标玩家 " + toPlayerUUID + " 不在任何服务器中");
            return;
        }
        for (UUID uuid : event.getSendPlayerUUID()) {
            Player sendPlayer = proxyServer.getPlayer(uuid).orElse(null);
            if (sendPlayer == null) {
                continue;
            }
            ServerInfo currentServer = sendPlayer.getCurrentServer().map(ServerConnection::getServerInfo).orElse(null);
            if (currentServer != null && currentServer.getName().equals(toServer.getServerInfo().getName())) {
                continue;
            }
            sendPlayer.createConnectionRequest(toServer).fireAndForget();
        }
    }
}
